//	---------------------------------------------------------------------------
//
//	@file		MiniSFML16.h
//	@brief		A subset of SFML 1.6 definitions needed to compile helper
//				functions implemented in TwEventSFML.cpp
//
//	notes:	  - Private header
//			  - AntTweakBar.dll does not need to link with SFML,
//				it just needs some definitions for its helper functions.
//			  - This header is provided to avoid the need of having SFML
//				installed to recompile AntTweakBar.
//				It declares a small and incomplete part of SFML classes.
//				For instance, many non-virtual methods have been stripped out.
//			  - Do not use this header in your own programs, better use the
//				SFML headers from the actual SFML library SDK :
//				http://www.sfml-dev.org
//
//	---------------------------------------------------------------------------

#if !defined MINI_SFML16_INCLUDED
#define MINI_SFML16_INCLUDED

namespace sf
{

	namespace Key { enum Code
	{
		A = 'a', B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z,
		Num0 = '0', Num1, Num2, Num3, Num4, Num5, Num6, Num7, Num8, Num9,
		Escape = 256,
		LControl, LShift, LAlt, LSystem,
		RControl, RShift, RAlt, RSystem, Menu,
		LBracket, RBracket, SemiColon, Comma, Period, Quote, Slash, BackSlash,
		Tilde, Equal, Dash, Space, Return, Back, Tab,
		PageUp, PageDown, End, Home, Insert, Delete,
		Add, Subtract, Multiply, Divide, Left, Right, Up, Down,
		Numpad0, Numpad1, Numpad2, Numpad3, Numpad4, Numpad5, Numpad6, Numpad7, Numpad8, Numpad9,
		F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, Pause,
		Count
	}; }

	namespace Mouse { enum Button { Left, Right, Middle, XButton1, XButton2, Count }; }

	namespace Joy { enum Axis { AxisX, AxisY, AxisZ, AxisR, AxisU, AxisV, AxisPOV, AxisCount };
					enum { Count = 4, ButtonCount = 32}; }

	typedef unsigned char Uint8;
	typedef unsigned int Uint32;

	class Event
	{
	public :
		struct KeyEvent { Key::Code Code; bool Alt, Control, Shift; };
		struct TextEvent { Uint32 Unicode; };
		struct MouseMoveEvent { int X, Y; };
		struct MouseButtonEvent { Mouse::Button Button; int X, Y; };
		struct MouseWheelEvent { int Delta; };
		struct JoyMoveEvent { unsigned int JoystickId; Joy::Axis Axis; float Position; };
		struct JoyButtonEvent { unsigned int JoystickId, Button; };
		struct SizeEvent { unsigned int Width, Height; };
		enum EventType
		{
			Closed, Resized, LostFocus, GainedFocus, TextEntered, KeyPressed, KeyReleased,
			MouseWheelMoved, MouseButtonPressed, MouseButtonReleased, MouseMoved, MouseEntered, MouseLeft,
			JoyButtonPressed, JoyButtonReleased, JoyMoved
		};
		EventType Type;
		union
		{
			KeyEvent		 Key;
			TextEvent		 Text;
			MouseMoveEvent	 MouseMove;
			MouseButtonEvent MouseButton;
			MouseWheelEvent  MouseWheel;
			JoyMoveEvent	 JoyMove;
			JoyButtonEvent	 JoyButton;
			SizeEvent		 Size;
		};
	};

} // namespace sf


#ifdef USE_MINI_SFML
// we also need some the definition of sf::RenderWindow to compile our SFML example

#include <string>
#include <queue>

namespace sf
{

	class Input;
	class Drawable;
	typedef void* WindowHandle;
	namespace priv { class WindowImpl; }

	class WindowListener
	{
	public :
		virtual void OnEvent(const Event& EventReceived) = 0;
	protected :
		virtual ~WindowListener();
	};

	class VideoMode
	{
	public :
		VideoMode(unsigned int ModeWidth, unsigned int ModeHeight, unsigned int ModeBpp = 32);
		unsigned int Width, Height, BitsPerPixel;
	};

	namespace Style { enum { None = 0, Titlebar = 1 << 0, Resize = 1 << 1, Close = 1 << 2, Fullscreen = 1 << 3 }; }

	struct WindowSettings
	{
		explicit WindowSettings(unsigned int Depth = 24, unsigned int Stencil = 8, unsigned int Antialiasing = 0);
		unsigned int DepthBits, StencilBits, AntialiasingLevel;
	};

	class Clock
	{
	public :
		Clock();
		float GetElapsedTime() const;
		void Reset();
	private :
		double myStartTime;
	};

	class Input : public WindowListener
	{
	private :
		virtual void OnEvent(const Event& EventReceived);
		bool  myKeys[Key::Count];
		bool  myMouseButtons[Mouse::Count];
		int   myMouseX;
		int   myMouseY;
		bool  myJoystickButtons[Joy::Count][Joy::ButtonCount];
		float myJoystickAxis[Joy::Count][Joy::AxisCount];
	};

	class Window : public WindowListener
	{
	public :
		Window(VideoMode Mode, const std::string& Title, unsigned long WindowStyle = Style::Resize | Style::Close, const WindowSettings& Params = WindowSettings());
		virtual ~Window();
		void Close();
		bool IsOpened() const;
		unsigned int GetWidth() const;
		unsigned int GetHeight() const;
		bool GetEvent(Event& EventReceived);
		void Display();
	private :
		virtual void OnCreate();
		virtual void OnEvent(const Event& EventReceived);
		priv::WindowImpl* myWindow;
		std::queue<Event> myEvents;
		Input			  myInput;
		Clock			  myClock;
		WindowSettings	  mySettings;
		float			  myLastFrameTime;
		bool			  myIsExternal;
		unsigned int	  myFramerateLimit;
		int				  mySetCursorPosX;
		int				  mySetCursorPosY;
	};

	template <typename T> class Vector2 { public : T x, y; };
	typedef Vector2<float> Vector2f;

	template <typename T> class Rect { public : T Left, Top, Right, Bottom; };
	typedef Rect<float> FloatRect;

	class Matrix3 { private : float myData[16]; };

	class View
	{
	private :
		sf::Vector2f myCenter;
		sf::Vector2f myHalfSize;
		FloatRect	 myRect;
		Matrix3		 myMatrix;
		bool		 myNeedUpdate;
	};

	class RenderTarget
	{
	public :
		virtual ~RenderTarget();
		virtual void Draw(const Drawable& Object);
		virtual unsigned int GetWidth() const = 0;
		virtual unsigned int GetHeight() const = 0;
		void PreserveOpenGLStates(bool Preserve);
	private :
		virtual bool Activate(bool Active) = 0;
		View		myDefaultView;
		const View* myCurrentView;
		bool		myPreserveStates;
		bool		myIsDrawing;
	};

	class RenderWindow : public Window, public RenderTarget
	{
	public :
		RenderWindow(VideoMode Mode, const std::string& Title, unsigned long WindowStyle = Style::Resize | Style::Close, const WindowSettings& Params = WindowSettings());
		virtual ~RenderWindow();
		virtual unsigned int GetWidth() const;
		virtual unsigned int GetHeight() const;
	private :
		virtual void OnCreate();
		virtual bool Activate(bool Active);
	};

} // namespace sf

#endif // USE_MINI_SFML

#endif // !defined MINI_SFML16_INCLUDED

